package com.tuniondata.netty.client;

import com.tuniondata.netty.bean.ApiBinaryBean;
import com.tuniondata.netty.bean.MessageDecoder;
import com.tuniondata.netty.bean.MessageEncoder;
import com.tuniondata.netty.common.protocol.Protocol;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Netty 客户端
 * 于欣朝
 */
public class NettyClient {
    private static Logger logger = LoggerFactory.getLogger(NettyClient.class);
    private EventLoopGroup group = null;

    private ChannelFuture channelFuture;

    public ChannelFuture getChannelFuture() {
        return channelFuture;
    }

    public void setChannelFuture(ChannelFuture channelFuture) {
        this.channelFuture = channelFuture;
    }

    /**
     * 绑定服务器，进行通信
     * @param port 端口
     * @param ip 主机号
     */
    public void connect(int port, String ip) {
        logger.debug("port :" + port + " ip:" + ip);
        group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap
                .group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(
                        new IdleStateHandler(20, 10, 0),
                        new MessageDecoder(),
                        new MessageEncoder(),
                        new ApiClientHandler()
                    );
                    }
                });

            //发起异步链接操作
            ChannelFuture channelFuture = bootstrap.connect(ip, port).sync();
            Thread.sleep(3000);
            if (channelFuture.isSuccess()) {
                this.setChannelFuture(channelFuture);
                logger.info("connect server successfully");
                channelFuture.channel().flush();
            }
        } catch (Exception e) {
           logger.error(e.getMessage());
        }
    }

    /**
     * 关闭连接
     */
    public void close() {
        try {
            group.shutdownGracefully();
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            if (group != null) {
                //关闭，释放线程资源
                group.shutdownGracefully();
            }
        }
    }
}
